#include <assert.h>

#include <atomic>
#include <iostream>
#include <thread>

// 这个是对relaxed的加强，relax序由于无法限制多线程间的排序，
// 所以引入synchronized-with，但并不一定意味着，统一的操作顺序

std::atomic<bool> x, y;
std::atomic<int> z;

void write_x() { x.store(true, std::memory_order_seq_cst); }  // 1
void write_y() { y.store(true, std::memory_order_seq_cst); }  // 2
void read_x_then_y() {
  while (!x.load(std::memory_order_seq_cst))
    ;
  if (y.load(std::memory_order_seq_cst))  // 3
    ++z;
}
void read_y_then_x() {
  while (!y.load(std::memory_order_seq_cst))
    ;
  if (x.load(std::memory_order_seq_cst))  // 4
    ++z;
  z.fetch_sub(1, std::memory_order_acquire);
}
int main() {
  x = false;
  y = false;
  z = 0;
  std::thread a(write_x);
  std::thread b(write_y);
  std::thread c(read_x_then_y);
  std::thread d(read_y_then_x);
  a.join();
  b.join();
  c.join();
  d.join();
  assert(z.load() != 0);  // 5

  // 如果是relax内存序，会出现z=0的情况，毕竟两个写x，y的线程以及两读x-y，读y-x的线程没有顺序一致性要求，
  // 可能出现#1写好x，y数据，但x还在缓冲中，并没有放入内存，这时候读x的数据#4为false，
  // y写好数据，也放入缓冲，x也没有从内存读取新值， 所以#3也为false，z=0；
  // 两个线程的x，y数据不一致，这种带有缓存违反顺序一致。

  std::cout << "----End!------\n";

  return 0;
}